﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Toolkit.Web.Helpers;
using System.Security.Cryptography;
using System.Web;

namespace Toolkit.Web.ViewComponents.DataGrid
{
    public class DataExpression
    {
        public DataExpression()
        {
        }

        public DataExpression(string value)
        {
            Value = value;
        }

        public DataExpression(string encoded, string encrypted)
        {
            SetIfValid(encoded, encrypted);
        }

        public string Value
        {
            get;
            set;
        }

        public string Encoded
        {
            get
            {
                if (!string.IsNullOrEmpty(Value))
                {
                    return Base64Encoding.Encode(Value);
                }
                else
                {
                    return null;
                }
            }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    Value = Base64Encoding.Decode(value);
                }
                else
                {
                    Value = null;
                }
            }
        }

        public string Encrypted
        {
            get
            {
                if (!string.IsNullOrEmpty(Value))
                {
                    return EncodeExpression(Value);
                }
                else
                {
                    return null;
                }
            }
        }

        public bool IsValid(string encrypted)
        {
            return !HasBeenTamperedWith(Value, encrypted);
        }

        public void SetIfValid(string encoded, string encrypted)
        {
            Encoded = encoded;

            if (!IsValid(encrypted))
            {
                Value = null;
            }
        }

        private string EncodeExpression(string plainText)
        {
            if (string.IsNullOrEmpty(plainText))
            {
                throw new ArgumentException("planText");
            }

            using (HMACSHA1 hmacsha1 = new HMACSHA1(GetBytesFromString("31B6E8BE-65BD-47fc-B054-33232557C9C5")))
            {
                // Base64 encode the hmacsha1 bytes. This uses a url-safe version of the Base64 encoding
                // algorithm that does not output designated url characters such as /, +, ?, etc.
                return HttpServerUtility.UrlTokenEncode(hmacsha1.ComputeHash(GetBytesFromString(plainText)));
            }
        }

        private byte[] GetBytesFromString(string text)
        {
            return Encoding.UTF8.GetBytes(text);
        }

        private bool HasBeenTamperedWith(string expression, string token)
        {
            // Do not verify if no sort expression was given.
            if (string.IsNullOrEmpty(expression))
            {
                return false;
            }

            if (string.IsNullOrEmpty(token))
            {
                return true;
            }

            return (EncodeExpression(expression) != token);
        }
    }
}
